//
//  PathsAnimation.swift
//  animations
//
//  Created by Ekaterina on 12.01.2023.
//

import SwiftUI

struct PathAnimationView: View {
    @Namespace var animationNamespace
    
    @State var isCircle = true;
    @State var duration = 1.0;
    @State var rotation = 45.0;
    @State var size = 100.0
    @State var stroke = 5.0
    
    let minDuration = 0.1
    let maxDuration = 2.0
    let minRotation = 0.0
    let maxRotation = 360.0
    let minSize = 30.0
    let maxSize = 150.0
    let minStroke = 1.0
    let maxStroke = 15.0
    
    var body: some View {
        VStack {
            OvalShape(isCircle: isCircle, rotation: rotation)
                .stroke(.red, lineWidth: stroke)
                .frame(width: size, height: size)
                .padding(.vertical, 24)
            Spacer()
            VStack(spacing: 16) {
                Divider()
                ValueSlider(title: "Duration", minValue: minDuration, maxValue: maxDuration, value: $duration)
                ValueSlider(title: "Rotation", minValue: minRotation, maxValue: maxRotation, value: $rotation)
                ValueSlider(title: "Size", minValue: minSize, maxValue: maxSize, value: $size)
                ValueSlider(title: "Stroke", minValue: minStroke, maxValue: maxStroke, value: $stroke)
                PlayButton {
                    withAnimation(.easeInOut(duration: duration)) {
                        isCircle.toggle()
                    }
                }
            }
        }
        .navigationTitle("Path Animation")
        .navigationBarTitleDisplayMode(.inline)
        .padding(24)
    }
}

struct OvalShape: Shape {
    private var round: Double
    private var rotation: Double
    
    var animatableData: AnimatablePair<Double, Double> {
        get { return AnimatablePair(round, rotation) }
        set {
            round = newValue.first
            rotation = newValue.second
        }
    }
    
    init(isCircle: Bool, rotation: Double /*degrees*/) {
        self.round = isCircle ? 1 : 0
        self.rotation = isCircle ? 0 : rotation
    }
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        
        let roundX = (rect.width / 2) * round
        let roundY = (rect.height / 2) * round
        
        let transform = CGAffineTransform(translationX: rect.midX, y: rect.midY)
            .rotated(by: rotation * .pi / 180)
            .translatedBy(x: -rect.midX, y: -rect.midY)
        
        path.addRoundedRect(in: rect, cornerSize: CGSize(width: roundX, height: roundY), transform: transform)
        
        path.closeSubpath()
        return path
    }
}

struct PathsAnimation_Previews: PreviewProvider {
    static var previews: some View {
        PathAnimationView()
    }
}
